#include "../include/kernel/signal.h"
#include "../include/kernel/task.h"
#include "../include/s3c2410/cpu.h"
#include "../include/kernel/sys.h"

extern struct task_struct* current;

system_call3(int,singal,int,signum,unsigned int,handler,unsigned int,restorer)
system_call3(int,sigaction,int,signum,struct sigaction *,action,struct sigaction *,oldaction)


#define push_user_stack(a) \
{\
	(regs->sp)-=4;\
	*((unsigned int *)(regs->sp))=a;\
}

void do_signal_irq(int 	signr,struct cpu_registers *regs)
{
	int i;
	struct sigaction *sa=current->sigaction+(signr);
	
	unsigned int (*sa_handler)(int);

	sa_handler=(unsigned int )sa->sa_handler;

	if(sa_handler==SIG_IGN)
	{
		return ;
	}
	else if(sa_handler==SIG_DFL)
	{
		return ;
	}

	if(sa->sa_flags&SA_ONESHOT)
		sa->sa_handler=SIG_DFL;

	push_user_stack(regs->pc-4);
	push_user_stack(regs->lr);
	push_user_stack(regs->r12);
	push_user_stack(regs->r11);
	push_user_stack(regs->r10);
	push_user_stack(regs->r9);
	push_user_stack(regs->r8);
	push_user_stack(regs->r7);
	push_user_stack(regs->r6);
	push_user_stack(regs->r5);
	push_user_stack(regs->r4);
	push_user_stack(regs->r3);
	push_user_stack(regs->r2);
	push_user_stack(regs->r1);
	push_user_stack(regs->r0);

	regs->r0=signr;
	regs->lr=sa->sa_restorer;
	regs->pc=sa_handler+4;

	current->blocked|=sa->sa_mask;
}
